perm filename HELP.FAI[S,NET] blob sn#569490 filedate 1983-05-30 generic text, type T, neo UTF8
	ENTRY PHELP
	TITLE	HELP user from PUB file
	SEARCH TVRHDR

↓RET←1
↓TAC←RET+1
↓SP←16
↓P←17

↓IODEND←←20000

SUBR PHELP,CHAN,IOBLK,KEYSTR,OUTOP,FLAGS
COMMENT ⊗

Description:
   Searches an E format file for .PHELP <keystring>.  Normally, it then
prints text not preceded by '.' up to next .PHELP or a form feed is seen.
If the low order bit of the flag word is set, instead of printing the
following text, the rest of the line following .PHELP is printed instead.
This can be a one-line summary of the command.

⊗;
	ACCUMULATORS{TEM,P1,P2,CHN,HDR}

	LOCALS{HEADER,BUFPTR,BUFCNT}	;Make buffer header
	PUSHP TEM		;Save AC's we'll need
	PUSHP P1
	PUSHP P2
	PUSHP CHN
	PUSHP HDR
	MOVE CHN,CHAN		;Setup channel pointer
	MOVE P1,IOBLK
	PUSHP <[0]>		;Push OPEN mode
	PUSHP <(P1)>		;Push device name
	MOVEI HDR,HEADER
	PUSHP HDR		;Push buffer header
	MOVE RET,[OPEN 0,-2(P)]	;Construct OPEN instruction
	DPB CHN,[POINT 4,RET,12]
	XCT RET			;OPEN @CHN,-2(P)
	  JRST[	CALL WRASCZ↑,<[[ASCIZ/OPEN failed for help file.
/]]>,OUTOP
		SUB P,[XWD 3,3]		;Flush OPEN arguments from stack
		JRST LOSE ]
	SUB P,[XWD 3,3]↔.PLEVEL←←.PLEVEL-3	;Flush OPEN arguments from stack
	PUSHP <2(P1)>		;Push file name block
	PUSHP <3(P1)>
	PUSHP <4(P1)>
	PUSHP <5(P1)>
	ADD RET,[<LOOKUP 0,-3(P)>-<OPEN 0,-2(P)>]	;Turn OPEN into LOOKUP
	XCT RET			;LOOKUP @CHN,-3(P)
	  JRST[	CALL WRASCZ,<[[ASCIZ/LOOKUP failed for help file.
/]]>,OUTOP
		SUB P,[XWD 4,4]		;Flush LOOKUP arguments from stack
		JRST LOSE ]
	SUB P,[XWD 4,4]↔.PLEVEL←←.PLEVEL-4	;Flush LOOKUP arguments from stack
	PUSHP JOBREL		;Save pointer to end of memory for coring down
	PUSHP JOBFF		;This one, too, due primarily to SAIL
	MOVE RET,KEYSTR		;Get key string to make sure it's a string pointer
	TLNN RET,-1
	  HRLI RET,(<POINT 7,0>)
	MOVEM RET,KEYSTR
;Skip first two lines in directory page
	MOVEI TEM,2
DLFSRH:	PUSHJ P,GETCHR		;Get a character from buffer
	CAIN RET,14		;FF, that is, end of page?
	  PUSHJ P,[		;  Shouldn't happen in middle of page
		.PLEVEL←←.PLEVEL+1	;Account for PUSHJ
	BADFMT:	CALL WRASCZ,<[[ASCIZ/Help file not in E format.
/]]>,OUTOP
		POP P,RET		;Put losing PC in RET for debugging
		.PLEVEL←←.PLEVEL-1	;Account for PUSHJ again
		JRST DONE ]
	CAIE RET,12		;LF?
	  JRST DLFSRH		;  No, look some more
	SOJG TEM,DLFSRH
;	\ /
;Have a LF, consider new line
DGOTLF:	PUSHJ P,GETCHR		;GET "C"
	CAIN RET,14		;End of directory page?
	  JRST[				;Yes, it's not in the directory page
	NOHELP:	CALL WRASCZ,<[[ASCIZ/Help topic not found.
/]]>,OUTOP
		JRST DONE ]
	CAIE RET,"C"		;If not FF, must be 'C' (for comment in FORTRAN)
	  PUSHJ P,BADFMT		;Bad format. (Never returns)
	SETZ P1,		;Start accumulating a number
;	\ /
RECLP:	PUSHJ P,GETCHR		;Get a digit
	CAIL RET,"0"		;Is it really a digit?
	CAILE RET,"9"
	  JRST[	JUMPN P1,GOTREC		;Yes, make sure we got a number
		CAIE RET,"⊗"		;Terminate directory page?
		  PUSHJ P,BADFMT		;Bad format. (Never returns)
		JRST NOHELP ]
	IMULI P1,=10		;Accumulate decimal number
	ADDI P1,-"0"(RET)
	JRST RECLP
;	---
GOTREC:	CAIE RET," "		;Better be terminated with a space
	  PUSHJ P,BADFMT	;  Oops
;	\ /
;Have a space, look for dot, then start a string compare
DSPACE:	PUSHJ P,GETCHR		;Get first character of label
	CAIE RET,"."		;Is it a dot?
	  JRST DSPSRH		;  No, doesn't start a label.
	MOVE P2,KEYSTR		;Setup for comparison
DCMPLP:	PUSHJ P,GETCHR		;Get a character from file
	ILDB TEM,P2		;Get a character from string
	CAMN RET,TEM		;Same?
	  JRST DCMPLP		;  Yes, try another
	JUMPE TEM,DMAYBE	;No, but end of key string
	CAIL TEM,"a"		;Check also lower case
	CAIE RET,"A"-"a"(TEM)
	  JRST DSPSRH		;  No, doesn't match
	JRST DCMPLP		;Yes, matched the hard way.
;	---
DSPSRH:	CAIE RET,11		;TAB
	CAIN RET," "		;or space?
	  JRST DSPACE		;  Yes, start trying for another
	CAIN RET,12		;LF?
	  JRST DGOTLF		;  Yes, try a new line
	CAIN RET,14		;FF?
	  PUSHJ P,BADFMT	;  Ooops
	PUSHJ P,GETCHR		;Get another
	JRST DSPSRH		;And try again.
;	---
DMAYBE:	CAIE RET," "		;Terminated by space?
	CAIN RET,15		;Or return?
	  SKIPA			;  Yes, we got one!
	JRST DSPSRH		;No, look for another label
;	\ /
;We found a match.  Now, got to relevant record in file to search page for label
	MOVE RET,[USETI 0,(P1)]	;Construct instruction to set read pointer
	DPB CHN,[POINT 4,RET,12]
	XCT RET			;USETI @CHN,(P1)
	PUSHJ P,GETCHR		;Get FF
	CAIE RET,14		;Is it?
	  PUSHJ P,BADFMT	;  Ooops!
;	\ /
;Find next line
PLFSRH:	PUSHJ P,GETCHR		;Get a character from buffer
	CAIN RET,14		;FF, that is, end of page?
	  PUSHJ P,BADFMT	;  Shouldn't happen in middle of line
	CAIE RET,12		;LF?
	  JRST PLFSRH		;  No, look some more
;	\ /
;Have a LF, consider new line
PGOTLF:	PUSHJ P,GETCHR		;Get first character on line
	CAIN RET,14		;End of page?
	  JRST[				;Yes, it's not on that page!!!
		CALL WRASCZ,<[[ASCIZ/Help topic found in directory, but not specified page!
/]]>,OUTOP
		JRST DONE ]
	CAIE RET,"."		;If not '.', it's ordinary text to be ignored
	  JRST PLFSRH		;Bad format. (Never returns)
	MOVE P2,KEYSTR		;Setup for comparison
;	\ /
PCMPLP:	PUSHJ P,GETCHR		;Get a character from file
	ILDB TEM,P2		;Get a character from string
	CAMN RET,TEM		;Same?
	  JRST PCMPLP		;  Yes, try another
	JUMPE TEM,PMAYBE	;No, but end of key string
	CAIL TEM,"a"		;Check also lower case
	CAIE RET,"A"-"a"(TEM)
	  JRST PLFSRH		;  No, doesn't match
	JRST PCMPLP		;Yes, matched the hard way.
;	---
PMAYBE:	CAIE RET,":"		;Terminated by colon?
	  JRST PLFSRH		;No, not a label match
;	\ /
;We found a match.  Now, print text upto .HELPEND or <formfeed>
;	\ /
TLFSRH:	PUSHJ P,GETCHR		;Get a character from buffer
	CAIN RET,14		;FF, that is, end of page?
	  PUSHJ P,BADFMT	;  Shouldn't happen in middle of linr
	CAIE RET,12		;LF?
	  JRST TLFSRH		;  No, look some more
;	\ /
;Have a LF, consider new line
TGOTLF:	PUSHJ P,GETCHR		;Get first character on line
	CAIN RET,14		;End of page?
	  JRST DONE			;Yes, we're done printing things
	CAIN RET,"{"		;PUB escape, more on line later
	  JRST TSKPUB		;  Yes, look for some real text.
	CAIE RET,"."		;If not '.', it's ordinary text to be ignored
	  JRST TTYPLN		;  Yep, print the text
	SKIPA P2,[POINT 7,[ASCIZ/.HELPEND/]]	;Setup for comparison
;	\ / (skips)
TCMPLP:	PUSHJ P,GETCHR		;Get a character from file
	ILDB TEM,P2		;Get a character from string
	CAMN RET,TEM		;Same?
	  JRST TCMPLP		;  Yes, try another
	JUMPE TEM,DONE		;No, but we found match, i.e. end of topic
	JRST TLFSRH		;Doesn't match.  Flush rest of command line
;	---
;Type a line of text
TTYPLN:	XCT OUTOP		;Output a character
TTYPL1:	PUSHJ P,GETCHR
	CAIN RET,"≡"		;Quote next thing?
	  JRST[	PUSHJ P,GETCHR	;  Yes, quote anything
		JRST TTYPLN ]
	CAIN RET,"{"		;PUB escape?
	  JRST TSKPUB
	CAIN RET,14		;End of page?
	  PUSHJ P,BADFMT	;  Sure, but in the middle of a line???
	CAIE RET,12		;End of line yet?
	  JRST TTYPLN		;  No, more to print
	XCT OUTOP		;Yes, print it
	JRST TGOTLF		;Now, consider new line
;	---
;PUB escape seen.  Skip to end of it (we hope)
TSKPUB:	PUSHJ P,GETCHR
	CAIN RET,14		;End of page?
	  PUSHJ P,BADFMT	;  They've got to be kidding...
	CAIN RET,12		;End of line
	  JRST TGOTLF		;  Yes, we'll stop in the middle of the line!
	CAIE RET,"}"		;End of PUB junk?
	  JRST TSKPUB		;  No, more to skip
	JRST TTYPL1		;Yes, get another character and rejoin typeout
;	---
DONE:	MOVSI TEM,(<RELEASE 0,>)
	DPB CHN,[POINT 4,TEM,12]
	XCT TEM			;RELEASE @CHN,
	POPP JOBFF		;Restore JOBFF
	POPP TEM		;Get back old JOBREL
	CAME TEM,JOBREL		;Did we expand for buffer ring?
	  CORE TEM,		;  Yes, core down.
	  JFCL			;  This should always work, but...
;	\ /
LOSE:	POPP HDR		;Restore AC's we used
	POPP CHN
	POPP P2
	POPP P1
	POPP TEM
	RETURN

;Standard buffered mode read.
GETCHR:	SOSLE 2(HDR)		;Are there enough characters left?
	  JRST GOTCHR		;  Yes, return one
	MOVE RET,[IN 0,]
	DPB CHN,[POINT 4,RET,12]	;Setup channel number
	XCT RET			;IN @CHN,
	  JRST GOTCHR		;  No errors
	ADD RET,[<STATO 0,IODEND> - <IN 0,>]	;Convert to STATO
	XCT RET			;STATZ @CHN,IODEND	(Check end of file)
	  OUTSTR [ASCIZ/% Warning:  Read error from Help file!
/]
	MOVEI RET,14		;Return a FF, we stop on any variety of end of
	POPJ P,			;page
;	---
GOTCHR:	ILDB RET,1(HDR)		;Get character from file.
	JUMPE RET,GETCHR	;Flush nulls
	POPJ P,

SUBREND PHELP

END